package com.seafood.service.impl;

import com.seafood.dto.ShoppingCartDTO;
import com.seafood.entity.Product;
import com.seafood.entity.ShoppingCart;
import com.seafood.entity.User;
import com.seafood.exception.BusinessException;
import com.seafood.repository.ProductRepository;
import com.seafood.repository.ShoppingCartRepository;
import com.seafood.repository.UserRepository;
import com.seafood.service.ShoppingCartService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 购物车服务实现类
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class ShoppingCartServiceImpl implements ShoppingCartService {
    
    private final ShoppingCartRepository shoppingCartRepository;
    private final UserRepository userRepository;
    private final ProductRepository productRepository;
    
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    @Override
    public ShoppingCartDTO addToCart(Long userId, Long productId, Integer quantity) {
        // 验证用户是否存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        // 验证商品是否存在
        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new BusinessException("商品不存在"));
        
        // 检查商品状态
        if (product.getStatus() != Product.ProductStatus.ACTIVE) {
            throw new BusinessException("商品已下架，无法添加到购物车");
        }
        
        // 检查库存
        if (product.getStockQuantity() < quantity) {
            throw new BusinessException("库存不足，当前库存：" + product.getStockQuantity());
        }
        
        // 检查购物车中是否已存在该商品
        Optional<ShoppingCart> existingCartItem = shoppingCartRepository.findByUserIdAndProductId(userId, productId);
        
        ShoppingCart cartItem;
        if (existingCartItem.isPresent()) {
            // 如果已存在，更新数量
            cartItem = existingCartItem.get();
            int newQuantity = cartItem.getQuantity() + quantity;
            
            // 再次检查库存
            if (product.getStockQuantity() < newQuantity) {
                throw new BusinessException("库存不足，当前库存：" + product.getStockQuantity() + 
                        "，购物车已有：" + cartItem.getQuantity());
            }
            
            cartItem.setQuantity(newQuantity);
        } else {
            // 创建新的购物车项
            cartItem = new ShoppingCart();
            cartItem.setUser(user);
            cartItem.setProduct(product);
            cartItem.setQuantity(quantity);
        }
        
        ShoppingCart saved = shoppingCartRepository.save(cartItem);
        return convertToDTO(saved);
    }
    
    @Override
    public ShoppingCartDTO updateCartItem(Long userId, Long productId, Integer quantity) {
        // 查找购物车项
        ShoppingCart cartItem = shoppingCartRepository.findByUserIdAndProductId(userId, productId)
                .orElseThrow(() -> new BusinessException("购物车中不存在该商品"));
        
        // 检查库存
        Product product = cartItem.getProduct();
        if (product.getStockQuantity() < quantity) {
            throw new BusinessException("库存不足，当前库存：" + product.getStockQuantity());
        }
        
        cartItem.setQuantity(quantity);
        ShoppingCart saved = shoppingCartRepository.save(cartItem);
        return convertToDTO(saved);
    }
    
    @Override
    public void removeFromCart(Long userId, Long productId) {
        if (!shoppingCartRepository.existsByUserIdAndProductId(userId, productId)) {
            throw new BusinessException("购物车中不存在该商品");
        }
        
        shoppingCartRepository.deleteByUserIdAndProductId(userId, productId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<ShoppingCartDTO> getCartByUser(Long userId) {
        List<ShoppingCart> cartItems = shoppingCartRepository.findByUserIdOrderByCreatedAtDesc(userId);
        return cartItems.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public void clearCart(Long userId) {
        shoppingCartRepository.deleteByUserId(userId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public BigDecimal calculateCartTotal(Long userId) {
        List<ShoppingCart> cartItems = shoppingCartRepository.findByUserIdOrderByCreatedAtDesc(userId);
        
        return cartItems.stream()
                .map(item -> {
                    BigDecimal price = item.getProduct().getPrice();
                    BigDecimal quantity = BigDecimal.valueOf(item.getQuantity());
                    return price.multiply(quantity);
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    
    /**
     * 转换为DTO
     */
    private ShoppingCartDTO convertToDTO(ShoppingCart cart) {
        ShoppingCartDTO dto = new ShoppingCartDTO();
        dto.setId(cart.getId());
        dto.setUserId(cart.getUser().getId());
        dto.setProductId(cart.getProduct().getId());
        dto.setProductName(cart.getProduct().getName());
        dto.setProductImage(cart.getProduct().getImageUrl());
        dto.setProductPrice(cart.getProduct().getPrice());
        dto.setProductUnit(cart.getProduct().getUnit());
        dto.setStockQuantity(cart.getProduct().getStockQuantity());
        dto.setQuantity(cart.getQuantity());
        dto.setSubtotal(cart.getProduct().getPrice().multiply(BigDecimal.valueOf(cart.getQuantity())));
        dto.setInStock(cart.getProduct().getStockQuantity() >= cart.getQuantity());
        dto.setCreatedAt(cart.getCreatedAt().format(FORMATTER));
        dto.setUpdatedAt(cart.getUpdatedAt().format(FORMATTER));
        
        return dto;
    }
}